package se.hiq.wineo.client.widgets;

import se.hiq.wineo.client.WineServiceAsync;
import se.hiq.wineo.client.events.WineListLoadedEvent;
import se.hiq.wineo.shared.data.WineColor;
import se.hiq.wineo.shared.data.WineDescriptor;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.Panel;

public class WineFilter {
	
	public interface View {
		HasValue<String> getName();
		HasValue<String> getYear();
		HasValue<WineColor> getColor();
		HasClickHandlers getFilterButton();
		
		HasText getNumResults();
		
		void isFiltering(boolean filtering);
		void displayError(String errorMessage);
		
		void attach(Panel panel);
	}
	
	private final WineServiceAsync wineService;
	
	private final HandlerManager eventBus;
	private final View view;
	
	public WineFilter(HandlerManager eventBus, View view, WineServiceAsync wineService) {
		this.eventBus = eventBus;
		this.view = view;
		this.wineService = wineService;
		
		bindDisplay();
	}
	
	public void attach(Panel panel) {
		view.attach(panel);
	}
	
	public void onFilterButtonPressed(String name, String year, WineColor color) {
		runQuery(name, year, color);
	}
	
	public void onReceiveWineList(WineDescriptor[] result) {
	    view.getNumResults().setText(Integer.toString(result.length));
	    eventBus.fireEvent(new WineListLoadedEvent(result));
	    view.isFiltering(false);
	}
	
	public void runQuery(String name, String yearStr, WineColor color) {
		Integer year = null;
		if (yearStr != null && !yearStr.trim().equals("")) {
			try {
				year = Integer.parseInt(yearStr);
			} catch (NumberFormatException nfe) {
				view.displayError("Year must be given as a number");
				return; // no query
			}
		}
		view.isFiltering(true);
		wineService.getWines(name, year, color,
			 new AsyncCallback<WineDescriptor[]>() {
				@Override
				public void onSuccess(WineDescriptor[] result) {
					onReceiveWineList(result);
				}
				@Override
				public void onFailure(Throwable caught) {
					view.isFiltering(false);
					Window.alert("Error: " + caught.toString());
				}
			});
	}
	
	private void bindDisplay() {
		view.getFilterButton().addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				onFilterButtonPressed(view.getName().getValue(), view.getYear().getValue(), view.getColor().getValue());
			}
		});
	}
	
}
